package com.example.my_bookkeeping;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;

import static org.hamcrest.Matchers.allOf;

import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

import androidx.recyclerview.widget.RecyclerView;
import androidx.test.espresso.ViewInteraction;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;

import com.example.my_bookkeeping.data.manager.BookKeepManager;
import com.example.my_bookkeeping.data.manager.UserManager;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

@LargeTest
@RunWith(AndroidJUnit4.class)
public class BookKeepDataShowTest {
    @Rule
    public ActivityScenarioRule<MainActivity> mActivityScenarioRule =
            new ActivityScenarioRule<>(MainActivity.class);

    private UserManager userManager;

    @Before
    public void setUp() {
        // 添加数据
        userManager = UserManager.getInstance();
        userManager.reset();
        BookKeepManager.getInstance().add("2023-10-01", 100.0, "餐饮", "测试备注", false);
    }

    @After
    public void tearDown() {
        userManager.reset();
    }

    @Test
    public void testBookKeepDataDisplayed() throws InterruptedException {
        ViewInteraction bottomNavigationItemView = onView(
                allOf(withId(R.id.item_bookkeep), withContentDescription("账目管理"),
                        childAtPosition(
                                childAtPosition(
                                        withId(R.id.bottom_navigation_view),
                                        0),
                                3),
                        isDisplayed()));
        bottomNavigationItemView.perform(click());

        Thread.sleep(1000);

        // 检查第一个 item 的各字段是否正确显示
        onView(withRecyclerView(R.id.recyclerView_record).atPositionOnView(0, R.id.tv_time))
                .check(matches(withText("2023-10-01")));

        onView(withRecyclerView(R.id.recyclerView_record).atPositionOnView(0, R.id.tv_amount))
                .check(matches(withText("100.0")));

        onView(withRecyclerView(R.id.recyclerView_record).atPositionOnView(0, R.id.tv_category))
                .check(matches(withText("餐饮")));

        onView(withRecyclerView(R.id.recyclerView_record).atPositionOnView(0, R.id.tv_type))
                .check(matches(withText("支出")));

        onView(withRecyclerView(R.id.recyclerView_record).atPositionOnView(0, R.id.tv_remark))
                .check(matches(withText("测试备注")));
    }

    // 自定义 RecyclerViewMatcher 工具类
    public static RecyclerViewMatcher withRecyclerView(final int recyclerViewId) {
        return new RecyclerViewMatcher(recyclerViewId);
    }

    public static class RecyclerViewMatcher {
        private final int recyclerViewId;

        public RecyclerViewMatcher(int recyclerViewId) {
            this.recyclerViewId = recyclerViewId;
        }

        public Matcher<View> atPositionOnView(final int position, final int targetViewId) {
            return new TypeSafeMatcher<View>() {
                @Override
                protected boolean matchesSafely(View view) {
                    RecyclerView recyclerView = view.getRootView().findViewById(recyclerViewId);
                    if (recyclerView == null || recyclerView.getId() != recyclerViewId) return false;
                    RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(position);
                    if (viewHolder == null) return false;
                    View targetView = viewHolder.itemView.findViewById(targetViewId);
                    return view == targetView;
                }

                @Override
                public void describeTo(Description description) {
                    description.appendText("View with id " + targetViewId + " at position " + position + " in RecyclerView");
                }
            };
        }
    }

    private static Matcher<View> childAtPosition(
            final Matcher<View> parentMatcher, final int position) {

        return new TypeSafeMatcher<View>() {
            @Override
            public void describeTo(Description description) {
                description.appendText("Child at position " + position + " in parent ");
                parentMatcher.describeTo(description);
            }

            @Override
            public boolean matchesSafely(View view) {
                ViewParent parent = view.getParent();
                return parent instanceof ViewGroup && parentMatcher.matches(parent)
                        && view.equals(((ViewGroup) parent).getChildAt(position));
            }
        };
    }
}
